‘Win’ Your Fantasy Football Auction Draft

with Integer Programming and R

Major Dusty Turner

Department of Statistical Science at Baylor University

In this talk we’ll win your fantasy football league using

ESPN API

Integer Programming

and

R

In this talk we’ll win your fantasy football league using

ESPN API

Integer Programming

and

R

But first…

I went for a run today…

So I went for a run today…

A little about me

Professional Life

  • Engineer Officer
    • Training: Fort Leonard Wood Missouri
    • Platoon Leader: Hawaii (Iraq)
    • Company Commander: White Sands Missile Range, NM (Afghanistan)
  • Assistant Professor / Instructor
    • United States Miliary Academy, West Point, NY
  • Operations Research Systems Analyst (ORSA)
    • Center for Army Analysis: Fort Belvoir, VA

Educational Life

  • United States Military Academy, 2007
    • BS Operations Research
  • University of Missouri of Science and Technology, 2012
    • MS Engineering Management
  • THE Ohio State, 2016
    • MS Integrated Systems Engineering
    • Applied Statistics Minor
  • Baylor University, 2025 (Hopefully)
    • Statistics PhD Student

Best Life

  • Married Jill (2010)
    • Xichigan
    • Epic / Mayo Clinic
  • Cal (2013)
    • New Mexico
    • All Sports
  • Reese (2015)
    • Ohio
    • Dance / Sports

What I assume about you…

Football

Fantasy Football

Integer Programming

RStats

What I assume about you…

Football

What I assume about you…

Football

Fantasy Football

Integer Programming

RStats

What I assume about you…

Fantasy Football

What I assume about you…

Football

Fantasy Football

Integer Programming

RStats

What I assume about you…

Integer Programming

What I assume about you…

Football

Fantasy Football

Integer Programming

RStats

What I assume about you…

RStats

So what is this fantasy football thing…

I’m glad you asked

  1. Fantasy football is a weekly game where team managers head-to-head with one other member in your league.

  2. Teams score points based off of the real life performance of players on their team.

  3. Teams that score more points than their opponent win.

Roster Make Up

  • 1 Quarterbacks
  • 2 Running back
  • 2 Wide Receiver
  • 1 Tight End
  • 1 Flex (RB, WR, or TE)
  • 1 Defense
  • 1 Kicker
  • Several bench players

Generally score points for yards gained, touchdowns scored, turnovers, field goals…

How do we select players?

Auction Draft

  1. Owners have $200 to bid on players auction style
  2. As players are nominated, the managers willing to spend the most money on the players gets him on their team
  3. The draft continues until all managers fill out their roster

Snake Draft

Players alternate selecting players until rosters are filled out.

We will look at the auction draft format

There are several strategies

  1. Spend lots of money on who we think are the best players
  2. Try to get bargains throughout the draft
  3. Maybe there’s a more intelligent strategy?

Enter: Integer Programming

Lets make some assumptions

  1. We know how many points a player is going to score throughout the year
  2. We know how much each player is worth

Goal: Maximize expected points

Subject to

  1. Expected cost of each player
  2. Roster configuration

Other pertinent information

  1. We do not care about the quality of our bench (spend 0 on bench)
  2. We are indifferent to our defense and kicker.

Lets get mathy

Maximize: \(\sum{p_{qrwt} * x_{qrwt}}\)

where \(p_{qrwt}\) is the expected points scored for player \(p_{qrwt}\)

\(q = 0, 1, 2, ... q\)

\(r = 0, 1, 2, ... r\)

\(w = 0, 1, 2, ... w\)

\(t = 0, 1, 2, ... t\)

\(x_{qrwt} \in (0,1)\)

Not so fast

Constraints

Football Position Constraints:

\(X_{1rwt} + X_{2rwt} + ... + X_{qrwt} = 1\) \(X_{q1wt} + X_{q2wt} + ... + X_{qrwt} \leq 3\) \(X_{qr1t} + X_{qr2t} + ... + X_{qrwt} \leq 3\) \(X_{qrw1} + X_{qrw2} + ... + X_{qrwt} \leq 2\) \(X_{q111} + X_{q211} + ... + X_{qrwt} = 6\)


Only 1 QB
At most 3 RBs
At most 3 WRs
At most 2 TEs
RB + WR + TE = 6

Financial Constraints

\(\sum_{q=0}^Q\sum_{r=0}^R\sum_{w=0}^W\sum_{t=0}^T C_{qrwt} * X_{qrwt} <= 200 \hspace{1cm}\)

So how do we get player data….?

I’m glad you asked

ESPNGet <- httr::RETRY(
    verb = "GET",
    )

I’m glad you asked

ESPNGet <- httr::RETRY(
    verb = "GET",
    url = paste0("https://fantasy.espn.com/apis/v3/games/ffl/seasons/2022/
    segments/0/leaguedefaults/3?scoringPeriodId=0&view=kona_player_info")
)

I’m glad you asked

ESPNGet <- httr::RETRY(
    verb = "GET",
    url = paste0("https://fantasy.espn.com/apis/v3/games/ffl/seasons/2022/
    segments/0/leaguedefaults/3?scoringPeriodId=0&view=kona_player_info"),
    query = list(view = "kona_player_info"),
    httr::accept_json()
  )

I’m glad you asked

ESPNGet <- httr::RETRY(
    verb = "GET",
    url = paste0("https://fantasy.espn.com/apis/v3/games/ffl/seasons/2022/
    segments/0/leaguedefaults/3?scoringPeriodId=0&view=kona_player_info"),
    query = list(view = "kona_player_info"),
    httr::accept_json(),
    httr::add_headers(
      `X-Fantasy-Filter` = jsonlite::toJSON(
        x = list(players = list(limit = 500,
                                sortPercOwned = list(sortAsc = FALSE,
                                                     sortPriority = 1
                                                     ))),
            auto_unbox = TRUE))
   )

I’m glad you asked

ESPNGet <- httr::RETRY(
    verb = "GET",
    url = paste0("https://fantasy.espn.com/apis/v3/games/ffl/seasons/2022/
    segments/0/leaguedefaults/3?scoringPeriodId=0&view=kona_player_info"),
    query = list(view = "kona_player_info"),
    httr::accept_json(),
    httr::add_headers(
      `X-Fantasy-Filter` = jsonlite::toJSON(
        x = list(players = list(limit = 500,
                                sortPercOwned = list(sortAsc = FALSE,
                                                     sortPriority = 1
                                                     ))),
            auto_unbox = TRUE)))
            
ESPNRaw <- rawToChar(ESPNGet$content)
ESPNFromJSON <- jsonlite::fromJSON(ESPNRaw)

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Make Tibble of 1 Player’s Data

get_player_projection <- function(id){
  tibble(fpts = ESPNFromJSON$players$player$stat[[id]]$appliedTotal,
         season = ESPNFromJSON$players$player$stat[[id]]$seasonId, 
         score_per_id = ESPNFromJSON$players$player$stat[[id]]$scoringPeriodId) |>
  filter(score_per_id == 0) |> 
  mutate(player = ESPNFromJSON$players$player$fullName[id]) |> 
  mutate(position = ESPNFromJSON$players$player$defaultPositionId[id]) |> 
  filter(season == 2022) |> 
  filter(fpts == max(fpts)) |> 
mutate(value = ESPNFromJSON$players$player$draftRanksByRankType$PPR$auctionValue[id])
}

Show one example for Jared

get_player_projection(id = 1) |> gt::gt()
fpts season score_per_id jsonid player position value
258.2525 2022 0 2 Stefon Diggs 3 44
ESPN_results <- 
  1:length(ESPNFromJSON$players$draftAuctionValue) |> 
  map_dfr(~get_player_projection(id = .x)) 

Clean Results for Linear Model

ESPN_results <- 
  1:length(ESPNFromJSON$players$draftAuctionValue) |> 
  map_dfr(~get_player_projection(id = .x)) 

Clean Results for Linear Model

ESPN_results <- 
  1:length(ESPNFromJSON$players$draftAuctionValue) |> 
  map_dfr(~get_player_projection(id = .x)) |>
  group_by(player) |> slice(1) |> ungroup() |> 
  mutate(position = case_when(position == 1 ~ "QB",
                              position == 2 ~ "RB",
                              position == 3 ~ "WR",
                              position == 4 ~ "TE",
                              position == 5 ~ "K",
                              position == 16 ~ "DEF")) |> 
  mutate(points_per_dollar = fpts / value) |> 
  filter(!is.infinite(points_per_dollar)) |> 
  filter(!is.nan(points_per_dollar)) |> 
  mutate(position_qb = ifelse(position == "QB",1,0)) |> 
  mutate(position_rb = ifelse(position == "RB",1,0)) |> 
  mutate(position_wr = ifelse(position == "WR",1,0)) |> 
  mutate(position_te = ifelse(position == "TE",1,0)) |> 
  mutate(position_flex = ifelse(position %in% c("RB","WR","TE"),1,0)) |>
  filter(position %in% c("QB","WR","RB","TE")) 

Example of Results

fpts player value points_per_dollar position_qb position_rb position_wr position_te position_flex
QB
271 Tua Tagovailoa 1 271 1 0 0 0 0
269 Kirk Cousins 1 269 1 0 0 0 0
261 Derek Carr 1 261 1 0 0 0 0
261 Trevor Lawrence 1 261 1 0 0 0 0
253 Justin Fields 1 253 1 0 0 0 0
284 Trey Lance 2 142 1 0 0 0 0
310 Aaron Rodgers 3 103 1 0 0 0 0
307 Dak Prescott 3 102 1 0 0 0 0
307 Tom Brady 3 102 1 0 0 0 0
302 Russell Wilson 3 101 1 0 0 0 0
294 Joe Burrow 3 98 1 0 0 0 0
286 Matthew Stafford 3 95 1 0 0 0 0
319 Jalen Hurts 5 64 1 0 0 0 0
316 Lamar Jackson 8 40 1 0 0 0 0
314 Kyler Murray 8 39 1 0 0 0 0
328 Justin Herbert 10 33 1 0 0 0 0
352 Patrick Mahomes 11 32 1 0 0 0 0
375 Josh Allen 18 21 1 0 0 0 0
WR
164 Treylon Burks 1 164 0 0 1 0 1
163 Marvin Jones Jr. 1 163 0 0 1 0 1
159 Jahan Dotson 1 159 0 0 1 0 1
157 Robbie Anderson 1 157 0 0 1 0 1
151 Joshua Palmer 1 151 0 0 1 0 1
146 DeVante Parker 1 146 0 0 1 0 1
145 Jarvis Landry 1 145 0 0 1 0 1
185 Brandon Aiyuk 2 92 0 0 1 0 1
180 Chase Claypool 2 90 0 0 1 0 1
180 Robert Woods 2 90 0 0 1 0 1
175 Garrett Wilson 2 88 0 0 1 0 1
174 Chris Olave 2 87 0 0 1 0 1
174 Jakobi Meyers 2 87 0 0 1 0 1
173 Allen Lazard 2 86 0 0 1 0 1
172 Marquez Valdes-Scantling 2 86 0 0 1 0 1
169 Russell Gage 2 84 0 0 1 0 1
168 Tyler Boyd 2 84 0 0 1 0 1
157 Michael Gallup 2 78 0 0 1 0 1
150 DeAndre Hopkins 2 75 0 0 1 0 1
146 DJ Chark 2 73 0 0 1 0 1
135 Skyy Moore 2 67 0 0 1 0 1
186 Kadarius Toney 3 62 0 0 1 0 1
197 Tyler Lockett 5 39 0 0 1 0 1
192 DeVonta Smith 5 38 0 0 1 0 1
198 Elijah Moore 6 33 0 0 1 0 1
199 Hunter Renfrow 6 33 0 0 1 0 1
197 JuJu Smith-Schuster 6 33 0 0 1 0 1
198 Rashod Bateman 6 33 0 0 1 0 1
192 Adam Thielen 6 32 0 0 1 0 1
193 Drake London 6 32 0 0 1 0 1
207 Michael Thomas 7 30 0 0 1 0 1
201 Allen Robinson II 7 29 0 0 1 0 1
200 Christian Kirk 7 29 0 0 1 0 1
199 Amari Cooper 7 28 0 0 1 0 1
207 Gabe Davis 11 19 0 0 1 0 1
212 Darnell Mooney 12 18 0 0 1 0 1
209 Amon-Ra St. Brown 13 16 0 0 1 0 1
198 Chris Godwin 13 15 0 0 1 0 1
210 Courtland Sutton 15 14 0 0 1 0 1
212 Jerry Jeudy 15 14 0 0 1 0 1
212 DK Metcalf 17 12 0 0 1 0 1
212 Marquise Brown 17 12 0 0 1 0 1
215 Brandin Cooks 22 10 0 0 1 0 1
218 Jaylen Waddle 22 10 0 0 1 0 1
211 Mike Williams 22 10 0 0 1 0 1
218 Diontae Johnson 23 9 0 0 1 0 1
236 Michael Pittman Jr. 26 9 0 0 1 0 1
222 Terry McLaurin 25 9 0 0 1 0 1
221 A.J. Brown 26 8 0 0 1 0 1
235 DJ Moore 30 8 0 0 1 0 1
237 Tee Higgins 31 8 0 0 1 0 1
238 Keenan Allen 32 7 0 0 1 0 1
223 Mike Evans 30 7 0 0 1 0 1
252 CeeDee Lamb 40 6 0 0 1 0 1
254 Davante Adams 45 6 0 0 1 0 1
261 Deebo Samuel 44 6 0 0 1 0 1
258 Stefon Diggs 44 6 0 0 1 0 1
246 Tyreek Hill 38 6 0 0 1 0 1
313 Cooper Kupp 59 5 0 0 1 0 1
276 Ja'Marr Chase 54 5 0 0 1 0 1
288 Justin Jefferson 55 5 0 0 1 0 1
41 Rashid Shaheed NA NA 0 0 1 0 1
K
148 Evan McPherson 1 148 0 0 0 0 0
148 Matt Gay 1 148 0 0 0 0 0
145 Harrison Butker 1 145 0 0 0 0 0
144 Justin Tucker 1 144 0 0 0 0 0
141 Nick Folk 1 141 0 0 0 0 0
139 Brandon McManus 1 139 0 0 0 0 0
139 Daniel Carlson 1 139 0 0 0 0 0
134 Matt Prater 1 134 0 0 0 0 0
132 Graham Gano 1 132 0 0 0 0 0
132 Tyler Bass 1 132 0 0 0 0 0
45 Cameron Dicker NA NA 0 0 0 0 0
15 Taylor Bertolet NA NA 0 0 0 0 0
TE
147 Dawson Knox 1 147 0 0 0 1 1
146 Hunter Henry 1 146 0 0 0 1 1
146 Irv Smith Jr. 1 146 0 0 0 1 1
140 Noah Fant 1 140 0 0 0 1 1
136 Mike Gesicki 1 136 0 0 0 1 1
131 David Njoku 1 131 0 0 0 1 1
130 Tyler Higbee 1 130 0 0 0 1 1
146 Cole Kmet 2 73 0 0 0 1 1
144 Pat Freiermuth 2 72 0 0 0 1 1
150 Dallas Goedert 3 50 0 0 0 1 1
148 Zach Ertz 3 49 0 0 0 1 1
168 T.J. Hockenson 4 42 0 0 0 1 1
177 Dalton Schultz 5 35 0 0 0 1 1
188 Darren Waller 9 21 0 0 0 1 1
170 George Kittle 8 21 0 0 0 1 1
198 Kyle Pitts 21 9 0 0 0 1 1
235 Mark Andrews 36 7 0 0 0 1 1
239 Travis Kelce 34 7 0 0 0 1 1
DEF
144 Bills D/ST 1 144 0 0 0 0 0
136 Packers D/ST 1 136 0 0 0 0 0
128 Saints D/ST 1 128 0 0 0 0 0
125 Buccaneers D/ST 1 125 0 0 0 0 0
120 Ravens D/ST 1 120 0 0 0 0 0
112 49ers D/ST 1 112 0 0 0 0 0
112 Cowboys D/ST 1 112 0 0 0 0 0
109 Colts D/ST 1 109 0 0 0 0 0
109 Steelers D/ST 1 109 0 0 0 0 0
105 Dolphins D/ST 1 105 0 0 0 0 0
RB
130 Raheem Mostert 1 130 0 1 0 0 1
169 AJ Dillon 2 84 0 1 0 0 1
163 Rashaad Penny 2 81 0 1 0 0 1
151 James Robinson 2 76 0 1 0 0 1
151 Michael Carter 2 75 0 1 0 0 1
146 Kenneth Walker III 2 73 0 1 0 0 1
145 Melvin Gordon III 2 72 0 1 0 0 1
145 Nyheim Hines 2 72 0 1 0 0 1
127 James Cook 2 63 0 1 0 0 1
184 Dameon Pierce 4 46 0 1 0 0 1
183 Kareem Hunt 4 46 0 1 0 0 1
184 Rhamondre Stevenson 4 46 0 1 0 0 1
181 Antonio Gibson 4 45 0 1 0 0 1
174 Chase Edmonds 4 44 0 1 0 0 1
175 Damien Harris 4 44 0 1 0 0 1
177 Tony Pollard 4 44 0 1 0 0 1
168 Cordarrelle Patterson 4 42 0 1 0 0 1
242 Josh Jacobs 10 24 0 1 0 0 1
189 Devin Singletary 9 21 0 1 0 0 1
185 Miles Sanders 9 21 0 1 0 0 1
197 Elijah Mitchell 10 20 0 1 0 0 1
191 Clyde Edwards-Helaire 10 19 0 1 0 0 1
214 J.K. Dobbins 14 15 0 1 0 0 1
211 Breece Hall 19 11 0 1 0 0 1
214 Ezekiel Elliott 20 11 0 1 0 0 1
205 Travis Etienne Jr. 19 11 0 1 0 0 1
220 David Montgomery 21 10 0 1 0 0 1
216 Nick Chubb 24 9 0 1 0 0 1
243 Aaron Jones 32 8 0 1 0 0 1
228 Saquon Barkley 29 8 0 1 0 0 1
240 James Conner 33 7 0 1 0 0 1
239 Javonte Williams 35 7 0 1 0 0 1
259 Leonard Fournette 37 7 0 1 0 0 1
255 Alvin Kamara 46 6 0 1 0 0 1
254 D'Andre Swift 42 6 0 1 0 0 1
259 Joe Mixon 43 6 0 1 0 0 1
285 Austin Ekeler 58 5 0 1 0 0 1
147 Cam Akers 28 5 0 1 0 0 1
310 Christian McCaffrey 59 5 0 1 0 0 1
258 Dalvin Cook 49 5 0 1 0 0 1
264 Derrick Henry 52 5 0 1 0 0 1
317 Jonathan Taylor 61 5 0 1 0 0 1
265 Najee Harris 50 5 0 1 0 0 1
43 Caleb Huntley NA NA 0 1 0 0 1
15 Malik Davis NA NA 0 1 0 0 1
22 Raheem Blackshear NA NA 0 1 0 0 1
10 Ronnie Rivers NA NA 0 1 0 0 1
# A tibble: 1 × 1
  `sum(value)`
         <int>
1          200
[1] 200
[1] 111.7315

Down to business

Select a solver engine

lpSolve
CVXR
GLPK
rmpk
ompr

lpSolve

library(lpSolve)

f_obj <- ESPN_results |> pull(fpts) 

f_con <- matrix(c(ESPN_results |> pull(position_qb),
                  ESPN_results |> pull(position_qb),
                  ESPN_results |> pull(position_wr),
                  ESPN_results |> pull(position_te),
                  ESPN_results |> pull(position_flex),
                  ESPN_results |> pull(value)
                  ),nrow = 6, byrow = T)

f_dir <- c("=",  # qb
           "<=", # rb
           "<=", # wr
           "=",  # te
           "=",  # flex
           "<="  # price
           )

f_rhs <- c(1,
           3,
           3,
           1,
           6,
           200)

lpSolve

f_obj
  [1] 220.8450 242.5602 309.6636 192.1663 168.7530 172.5595 201.0691 254.8248
  [9] 198.9663 208.8567 181.2622 284.7332 215.0983 184.9182 210.6620  43.0000
 [17] 146.7111 252.4529 180.3594 174.0654 198.2010 174.4467 200.0144 309.9427
 [25] 190.5999 145.7789 312.9066 167.8848 210.4194 253.6564 306.5225 150.3319
 [33] 176.6624 258.4904 183.6543 174.5547 212.1800 187.7119 253.5925 219.9178
 [41] 131.4289 146.5585 150.4110 261.4620 260.6069 264.4697 146.4369 188.7177
 [49] 192.2315 218.1936 146.0351 234.5686 212.4284 192.7721 197.4233 198.3393
 [57] 214.2013 207.2314 175.3097 169.5924 146.3820 199.0347 145.8136 214.3026
 [65] 276.1680 159.0293 173.9179 318.5135 240.0416 126.7101 151.1312 144.9516
 [73] 238.9946 218.2261 212.2043 294.4468 258.9057 316.9915 374.6255 242.4000
 [81] 150.9300 197.0992 253.0926 328.0368 287.7986 186.1823 182.5312 237.6153
 [89] 145.9000 269.1750 197.6367 313.9962 316.4061 258.7434  15.4000 235.0536
 [97] 172.0591 211.7768 163.0784 285.7049 144.7162 150.5256 156.7192 236.1641
[105] 206.5802 223.3164 135.9019 211.4404 184.6540 265.4768 216.0374 139.8340
[113] 144.6376 144.1705 352.0207  21.6000 130.4284 162.9332  41.4000 197.9605
[121] 183.9000 157.0269 180.4381  10.0000 168.6893 302.4224 227.7660 134.9712
[129] 258.2525 168.0302 237.3114 221.9403 306.8348 177.2297 205.0117 238.7000
[137] 260.7133 284.0327 163.8437 271.0333 168.3101 130.3365 197.0118 246.4522
[145] 148.1828
f_con
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
[1,]    0    0    1    0    0    0    0    0    0     0     0     0     0     0
[2,]    0    0    1    0    0    0    0    0    0     0     0     0     0     0
[3,]    1    0    0    1    0    1    1    0    1     1     0     0     1     1
[4,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
[5,]    1    1    0    1    1    1    1    1    1     1     1     1     1     1
[6,]   26   32    3    6    2    2    7   46    7    13     4    58    22     2
     [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
[1,]     0     0     0     0     0     0     0     0     0     0     0     0
[2,]     0     0     0     0     0     0     0     0     0     0     0     0
[3,]     0     0     0     1     1     0     1     1     1     0     0     0
[4,]     0     0     0     0     0     0     0     0     0     0     0     1
[5,]     1     1     1     1     1     1     1     1     1     1     1     1
[6,]    19    NA    28    40     2     4    13     2     7    59    10     2
     [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38]
[1,]     0     0     0     0     1     0     0     0     0     0     0     0
[2,]     0     0     0     0     1     0     0     0     0     0     0     0
[3,]     1     0     1     0     0     0     0     0     0     0     1     0
[4,]     0     0     0     0     0     1     1     0     0     0     0     1
[5,]     1     1     1     1     0     1     1     1     1     1     1     1
[6,]    59     4    15    42     3     3     5    49     4     4    12     9
     [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50]
[1,]     0     0     0     0     0     0     1     0     0     0     0     0
[2,]     0     0     0     0     0     0     1     0     0     0     0     0
[3,]     1     0     0     0     1     1     0     0     1     0     1     1
[4,]     0     0     1     1     0     0     0     0     0     0     0     0
[5,]     1     1     1     1     1     1     0     1     1     1     1     1
[6,]    45    21     1     1     2    44     1    52     1     9     5    23
     [,51] [,52] [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62]
[1,]     0     0     0     0     0     0     0     0     0     0     0     0
[2,]     0     0     0     0     0     0     0     0     0     0     0     0
[3,]     1     1     1     1     0     1     0     1     1     0     0     1
[4,]     0     0     0     0     0     0     0     0     0     1     1     0
[5,]     1     1     1     1     1     1     1     1     1     1     1     1
[6,]     2    30    17     6    10     6    20    11     2     8     1     6
     [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72] [,73] [,74]
[1,]     0     0     0     0     0     1     0     0     0     0     0     0
[2,]     0     0     0     0     0     1     0     0     0     0     0     0
[3,]     0     0     1     1     1     0     0     0     0     1     0     1
[4,]     1     0     0     0     0     0     0     0     0     0     0     0
[5,]     1     1     1     1     1     0     1     1     1     1     1     1
[6,]     1    14    54     1     2     5    33     2     2     1    35    22
     [,75] [,76] [,77] [,78] [,79] [,80] [,81] [,82] [,83] [,84] [,85] [,86]
[1,]     0     1     0     0     1     0     0     0     1     1     0     0
[2,]     0     1     0     0     1     0     0     0     1     1     0     0
[3,]     1     0     0     0     0     0     1     1     0     0     1     1
[4,]     0     0     0     0     0     0     0     0     0     0     0     0
[5,]     1     0     1     1     0     1     1     1     0     0     1     1
[6,]    15     3    43    61    18    10     1     6     1    10    55     3
     [,87] [,88] [,89] [,90] [,91] [,92] [,93] [,94] [,95] [,96] [,97] [,98]
[1,]     0     0     0     1     0     1     1     0     0     0     0     0
[2,]     0     0     0     1     0     1     1     0     0     0     0     0
[3,]     0     1     0     0     0     0     0     0     0     0     1     1
[4,]     0     0     0     0     1     0     0     0     0     1     0     0
[5,]     1     1     1     0     1     0     0     1     1     1     1     1
[6,]     4    32     2     1    21     8     8    37    NA    36     2    17
     [,99] [,100] [,101] [,102] [,103] [,104] [,105] [,106] [,107] [,108]
[1,]     0      1      0      0      0      0      0      0      0      0
[2,]     0      1      0      0      0      0      0      0      0      0
[3,]     1      0      0      0      1      1      1      1      0      1
[4,]     0      0      0      0      0      0      0      0      1      0
[5,]     1      0      1      1      1      1      1      1      1      1
[6,]     1      3      2      2      2     26      7     30      1     22
     [,109] [,110] [,111] [,112] [,113] [,114] [,115] [,116] [,117] [,118]
[1,]      0      0      0      0      0      0      1      0      0      0
[2,]      0      0      0      0      0      0      1      0      0      0
[3,]      0      0      0      0      0      0      0      0      0      0
[4,]      0      0      0      1      0      1      0      0      0      0
[5,]      1      1      1      1      1      1      0      1      1      1
[6,]      9     50     24      1      2      2     11     NA      1      2
     [,119] [,120] [,121] [,122] [,123] [,124] [,125] [,126] [,127] [,128]
[1,]      0      0      0      0      0      0      0      1      0      0
[2,]      0      0      0      0      0      0      0      1      0      0
[3,]      1      1      0      1      1      0      1      0      0      1
[4,]      0      0      0      0      0      0      0      0      0      0
[5,]      1      1      1      1      1      1      1      0      1      1
[6,]     NA      6      4      1      2     NA      2      3     29      2
     [,129] [,130] [,131] [,132] [,133] [,134] [,135] [,136] [,137] [,138]
[1,]      0      0      0      0      1      0      0      0      1      1
[2,]      0      0      0      0      1      0      0      0      1      1
[3,]      1      0      1      1      0      0      0      0      0      0
[4,]      0      1      0      0      0      0      0      1      0      0
[5,]      1      1      1      1      0      1      1      1      0      0
[6,]     44      4     31     25      3      4     19     34      1      2
     [,139] [,140] [,141] [,142] [,143] [,144] [,145]
[1,]      0      1      0      0      0      0      0
[2,]      0      1      0      0      0      0      0
[3,]      1      0      1      0      1      1      0
[4,]      0      0      0      1      0      0      1
[5,]      1      0      1      1      1      1      1
[6,]      1      1      2      1      5     38      3

Solution

solution <-
  lp(
    direction = "max",
    objective.in =  f_obj,
    const.mat =  f_con,
    const.dir =  f_dir,
    const.rhs =  f_rhs, 
    all.bin = TRUE
  )

Solution

solution <-
  lp(
    direction = "max",
    objective.in =  f_obj,
    const.mat =  f_con,
    const.dir =  f_dir,
    const.rhs =  f_rhs, 
    all.bin = TRUE
  )
  
solution$solution
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
 [38] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 [75] 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
[112] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0

My Team

ESPN_results |>
  mutate(solution = solution$solution) |> 
  filter(solution == 1) |>
  select(fpts, player, position, value, points_per_dollar) |>
  mutate(dollars_per_point = fpts/value) |>
  arrange(position)
fpts player position exp_auction_value
375 Josh Allen QB 18
317 Jonathan Taylor RB 61
242 Josh Jacobs RB 10
239 Travis Kelce TE 34
313 Cooper Kupp WR 59
207 Gabe Davis WR 11
207 Michael Thomas WR 7

What’s Next

Round team out with 0 dollar players, k, and def
Handeling uncertainties at the
talk other applicaitons (Afghanistan, Price is Right)
show shiny application put my websight and twitter somewhere get this posted on my websight